package cn.edu.anan.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 数据源配置
 *
 * @author ThinkPad
 * @version 1.0
 * @date 2021/9/21 15:55
 */
@Configuration
@MapperScan(basePackages = "cn.edu.anan.dao", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {

    /**
     * 包扫描别名
     */
    @Value("${mysql.datasource.type-aliases-package}")
    private String typeAliasesPackage;

    /**
     *mapper映射文件位置
     */
    @Value("${mysql.datasource.mapper-locations}")
    private String mapperLocation;

    /**
     *mybatis配置文件位置
     */
    @Value("${mysql.datasource.config-location}")
    private String configLocation;

    /**
     * 写数据源
     * @return
     */
    @Primary
    @Bean
    @ConfigurationProperties(prefix = "mysql.datasource.write")
    public DataSource writeDataSource() {
        return new DruidDataSource();
    }

    /**
     * 读数据源
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "mysql.datasource.read")
    public DataSource readDataSource() {
        return new DruidDataSource();
    }

    /**
     * 配置sqlSessionFactory
     * @return
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

        bean.setDataSource(routingDataSource());
        bean.setTypeAliasesPackage(typeAliasesPackage);

        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        bean.setMapperLocations(resolver.getResources(mapperLocation));
        bean.setConfigLocation(resolver.getResource(configLocation));

        return bean.getObject();
    }

    /**
     * 设置数据源路由表
     * @return
     */
    @Bean
    public AbstractRoutingDataSource routingDataSource() {
        MyAbstractRoutingDataSource proxy = new MyAbstractRoutingDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>(2);

        targetDataSources.put(DbContextHolder.WRITE, writeDataSource());
        targetDataSources.put(DbContextHolder.READ, readDataSource());

        proxy.setDefaultTargetDataSource(writeDataSource());
        proxy.setTargetDataSources(targetDataSources);

        return proxy;
    }

    /**
     * 配置事务管理器
     * @return
     */
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager() {
        return new DataSourceTransactionManager(routingDataSource());
    }

}
